using System;
using Moq;
using NUnit.Framework;
using Tycho.Grammar;
using Tycho.Parser.Peg;

namespace Tycho.UnitTests.Grammar {
    [TestFixture]
    public class StringCompilerSpecification {
        [Test]
        public void ShouldCompileInterpolatedString () {
            ITerm term = TermParser.Parse ("string {interpolation-production: prod}");

            var productionCompiler = new Mock<IProductionCompiler> ();
            var context = new ProductionCompilerContext (new Mock<IProductionCompilerEnvironment> ().Object,
                                                         new Mock<IProductionLookup> ().Object,
                                                         new Mock<IDynamicGrammar> ().Object,
                                                         new Mock<IDeferredCompilations> ().Object);
            productionCompiler.Setup (p => p.Compile (It.Is<ITerm> (t => t.IsIdentifierTerm ("prod")), null, context)).Returns (new GrammarTree(IntegerProduction.CreateTerminal ()));
            var compiler = new StringCompiler (productionCompiler.Object);

            IProduction production = compiler.Compile (term, null, context).Production;

            production.ParseTerm ("\"this rules\"").ShouldBe ("'this rules'");
            production.ParseTerm ("'this rules'").ShouldBe ("'this rules'");
            var term1 = production.ParseTerm ("\"interpolated #8 value\"");
            term1.ShouldBe ("interpolated-string {components: ['interpolated ', 8, ' value']}");
        }

        [Test]
        public void ShouldCompileNonInterpolatedString () {
            ITerm term = TermParser.Parse ("string {}");

            var productionCompiler = new Mock<IProductionCompiler> ();
            var environment = new Mock<IProductionCompilerEnvironment> ();
            var context = new ProductionCompilerContext (environment.Object,
                                                         new Mock<IProductionLookup> ().Object,
                                                         new Mock<IDynamicGrammar> ().Object,
                                                         new Mock<IDeferredCompilations> ().Object);

            environment.Setup (e => e.Default).Returns (IdentifierProduction.CreateTerminal ());

            var compiler = new StringCompiler (productionCompiler.Object);
            IProduction production = compiler.Compile (term, null, context).Production;

            production.ParseTerm ("\"this rules\"").ShouldBe ("'this rules'");
            production.ParseTerm ("'this rules'").ShouldBe ("'this rules'");
            var term1 = production.ParseTerm ("\"interpolated #x value\"");
            term1.ShouldBe ("interpolated-string {components: ['interpolated ', x, ' value']}");
        }
    }
}